var a = 1;

var func1 = function () {
    var b = 2;
    var func2 = function () {
        var c = 3;

        console.log('b', b); // 2
        console.log('a', a); // 1
    }
    func2();
    console.log('c', c); // c is not defined
};

func1();


/**
 * f 返回了一个匿名函数的引用，它可以访问到 func()被调用时产生的环境，而局部变量 a 一直处在这个环境里。既然局部变量所在的环境还能被外界访问，这个局部变量就有了不被销毁的理由。在这里产生了一个闭包结构，局部变量的生命看起来被延续了
 */
var func = function () {
    var a = 1;

    return function () {
        a++;
        console.log(a);
    }
};

var f = func();

f();
f();
f();
f();

/**
 * 在闭包的帮助下，把每次循环的 i 值都封闭起来。当在事件函数中顺着作用域链中从内到外查找变量 i 时，会先找到被封闭在闭包环境中的 i，
 *  */

var Type = {};
for (var i = 0, type; type = ['String', 'Array', 'Number'][i++];) {
    (function (type) {
        Type['is' + type] = function (obj) {
            return Object.prototype.toString.call(obj) === '[object ' + type + ']';
        }
    })(type)
};
Type.isArray([]); // 输出：true 
Type.isString("str");